﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using GranitePackageSystem.GranitePackagingService;
using System.Collections.ObjectModel;
using GranitePackageSystem.Models;
using System.Collections.Specialized;
using GranitePackageSystem.Views.ChildWindows;

namespace GranitePackageSystem.Views.Deployment
{
    public partial class DeploymentApprovalView : Page
    {        
        private ObservableCollection<DistributionPoint> DeployToDPs;
        private ObservableCollection<DistributionPoint> DoNotDeployToDPs;
        ObservableCollection<ADSiteDistribution> siteList;
        Dictionary<string, ADSiteDistribution> tSiteList;
        private ObservableCollection<WorkLogEntry> workLog;

        private GranitePackagingService.Request currentRequest;
        private GranitePackagingService.Package packageData;
        private GranitePackagingService.Program programData;

        public DeploymentApprovalView()
        {
            InitializeComponent();
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            checkRoles();

            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();

            if (App.Current.Resources.Contains("Current Request"))
            {
                currentRequest = App.Current.Resources["Current Request"] as GranitePackagingService.Request;

                if (currentRequest.Stage.Equals("Deployment"))
                {
                    // Start Loading Package Information
                    busyIndicatorPackageInformation.IsBusy = true;
                    busyIndicatorPackageInformation.BusyContent = "Loading Package Data";
                    proxy.getPackageListCompleted += new EventHandler<getPackageListCompletedEventArgs>(proxy_getPackageListCompleted_INIT);
                    proxy.getPackageListAsync(currentRequest);

                    if(currentRequest.Status.Equals("Pending Approval"))
                    {
                        btnDeployToDPs.IsEnabled = true;
                        btnCreateAdvertisement.IsEnabled = false;

                        // Start Loading DP List
                        busyIndicatorDPs.IsBusy = true;
                        busyIndicatorDPs.BusyContent = "Loading Distribution Point Information";
                        busyIndicatorDestinationSites.IsBusy = true;
                        busyIndicatorDestinationSites.BusyContent = "Loading Destination Site Information";

                        proxy.getADGroupUserInfoCompleted += new EventHandler<getADGroupUserInfoCompletedEventArgs>(proxy_getADGroupUserInfoCompleted_INIT);
                        proxy.getADGroupUserInfoAsync(currentRequest.ADGroupName);
                        /*proxy.getRequestUsersCompleted += new EventHandler<getRequestUsersCompletedEventArgs>(proxy_getRequestUsersCompleted_INIT);
                        proxy.getRequestUsersAsync(currentRequest);*/
                    }
                    else
                    {
                        if (currentRequest.Status.Equals("Pending Advertisement"))
                        {
                            btnDeployToDPs.IsEnabled = false;
                            btnCreateAdvertisement.IsEnabled = true;

                            panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                            panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;
                        }
                        else
                        {
                            if (currentRequest.Status.StartsWith("Creating Advertement:"))
                            {
                                busyIndicatorMain.IsBusy = true;
                                busyIndicatorMain.BusyContent = "Creating Advertisement";
                                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_CreateAdvertisement);
                                proxy.getRequestAsync(currentRequest.requestID, 5);
                            }
                            else
                            {
                                busyIndicatorMain.BusyContent = "Deploying to DPs";
                                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_DeployToDPs);
                                proxy.getRequestAsync(currentRequest.requestID, 5);
                            }
                        }
                    }
                }
                else
                {
                    this.NavigationService.Navigate(new System.Uri("/Home", System.UriKind.Relative));
                }
            }
            else
            {
                this.NavigationService.Navigate(new System.Uri("/Home", System.UriKind.Relative));
            }
        }


        private void checkRoles()
        {
            Web.User user = WebContext.Current.User;
            bool userInARole = false;

            if (user.IsInRole("GENMILLS\\GPS_Administrators")) { userInARole = true; }
            if (user.IsInRole("GENMILLS\\GPS_DeploymentApprovers")) { userInARole = true; }

            if (userInARole) { }
            else { this.NavigationService.Navigate(new System.Uri("/Unauthorized", System.UriKind.Relative)); }
        }

        void proxy_getPackageListCompleted_INIT(object sender, getPackageListCompletedEventArgs e)
        {
            if (e.Result.Count > 0)
            {
                packageData = e.Result[0];

                boxPackageName.Text = packageData.Name.ToString();
                boxPackageSize.Text = packageData.PackageSize_MB.ToString();
                boxPackageVersion.Text = packageData.Version.ToString();

                busyIndicatorPackageInformation.IsBusy = false;
            }
            else
            {
                this.NavigationService.Navigate(new Uri("/Home", UriKind.Relative));
            }
        }
        void proxy_getRequestUsersCompleted_INIT(object sender, getRequestUsersCompletedEventArgs e)
        {
            siteList = new ObservableCollection<ADSiteDistribution>();
            tSiteList = new Dictionary<string, ADSiteDistribution>();

            foreach (RequestMember reqMember in e.Result)
            {
                if (tSiteList.ContainsKey(reqMember.ADSite))
                {
                    tSiteList[reqMember.ADSite].NumberOfUsers += 1;
                    tSiteList[reqMember.ADSite].Computer.Add(reqMember.comptuerName);
                }
                else
                {
                    tSiteList.Add(reqMember.ADSite, new ADSiteDistribution()
                    {
                        NumberOfUsers = 1,
                        ADSite = reqMember.ADSite,
                        Computer = new List<string>() { reqMember.comptuerName }
                    });
                }
            }

            foreach (String ADSite in tSiteList.Keys)
            {
                siteList.Add(new ADSiteDistribution()
                {
                    ADSite=ADSite,
                    NumberOfUsers=tSiteList[ADSite].NumberOfUsers,
                    Computer = tSiteList[ADSite].Computer
                });
            }

            gridDestinationSites.ItemsSource = siteList;

            busyIndicatorDestinationSites.IsBusy = false;

            // Load DP Information
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getSCCMDistributionPointsCompleted += new EventHandler<getSCCMDistributionPointsCompletedEventArgs>(proxy_getSCCMDistributionPointsCompleted_INIT);
            proxy.getSCCMDistributionPointsAsync();
        }

        void proxy_getADGroupUserInfoCompleted_INIT(object sender, getADGroupUserInfoCompletedEventArgs e)
        {
            siteList = new ObservableCollection<ADSiteDistribution>();
            tSiteList = new Dictionary<string, ADSiteDistribution>();

            foreach (RequestMember reqMember in e.Result)
            {
                if (tSiteList.ContainsKey(reqMember.ADSite))
                {
                    tSiteList[reqMember.ADSite].NumberOfUsers += 1;
                    tSiteList[reqMember.ADSite].Computer.Add(reqMember.comptuerName);
                }
                else
                {
                    tSiteList.Add(reqMember.ADSite, new ADSiteDistribution()
                    {
                        NumberOfUsers = 1,
                        ADSite = reqMember.ADSite,
                        Computer = new List<string>() { reqMember.comptuerName }
                    });
                }
            }

            foreach (String ADSite in tSiteList.Keys)
            {
                siteList.Add(new ADSiteDistribution()
                {
                    ADSite = ADSite,
                    NumberOfUsers = tSiteList[ADSite].NumberOfUsers,
                    Computer = tSiteList[ADSite].Computer
                });
            }

            gridDestinationSites.ItemsSource = siteList;

            busyIndicatorDestinationSites.IsBusy = false;

            // Load DP Information
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getSCCMDistributionPointsCompleted += new EventHandler<getSCCMDistributionPointsCompletedEventArgs>(proxy_getSCCMDistributionPointsCompleted_INIT);
            proxy.getSCCMDistributionPointsAsync();
        }
        void proxy_getSCCMDistributionPointsCompleted_INIT(object sender, getSCCMDistributionPointsCompletedEventArgs e)
        {
            DeployToDPs = new ObservableCollection<DistributionPoint>();
            DoNotDeployToDPs = new ObservableCollection<DistributionPoint>();
            foreach (DistributionPoint DP in e.Result)
            {
                bool found = false;
                foreach (String siteCode in tSiteList.Keys)
                {
                    if(siteCode.ToUpper().Equals(DP.SiteCode.ToUpper()))
                    {
                        DeployToDPs.Add(DP);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    DoNotDeployToDPs.Add(DP);
                }
            }

            gridAllDPs.ItemsSource = DoNotDeployToDPs;
            gridSuggestedDPs.ItemsSource = DeployToDPs;

            busyIndicatorDPs.IsBusy = false;

            busyIndicatorMain.BusyContent = "Getting Request Work Log Data";

            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getRequestWorkLogCompleted += new EventHandler<getRequestWorkLogCompletedEventArgs>(proxy_getRequestWorkLogCompleted_INIT);
            proxy.getRequestWorkLogAsync(currentRequest);
        }
        void proxy_getRequestWorkLogCompleted_INIT(object sender, getRequestWorkLogCompletedEventArgs e)
        {
            busyIndicatorMain.IsBusy = false;
            workLog = new ObservableCollection<WorkLogEntry>();
            if (e.Result.Count > 0)
            {
                foreach (WorkLogEntry entry in e.Result)
                {
                    WorkLogEntry modifiedEntry = entry;
                    modifiedEntry.NoteDate = modifiedEntry.NoteDate.ToLocalTime();

                    workLog.Add(modifiedEntry);
                }
            }
            gridWorkLog.ItemsSource = workLog;
        }

        private void btnAddDPsToDestinationDPs_Click(object sender, RoutedEventArgs e)
        {
            DistributionPoint[] tDPArray = new DistributionPoint[DoNotDeployToDPs.Count];
            DoNotDeployToDPs.CopyTo(tDPArray, 0);

            foreach (DistributionPoint DP in tDPArray)
            {
                if (DP.selected)
                {
                    DP.selected = false;
                    DoNotDeployToDPs.Remove(DP);
                    DeployToDPs.Add(DP);
                }
            }
        }

        private void btnRemoveDPsFromDestinationDPs_Click(object sender, RoutedEventArgs e)
        {
            DistributionPoint[] tDPArray = new DistributionPoint[DeployToDPs.Count];
            DeployToDPs.CopyTo(tDPArray, 0);

            foreach (DistributionPoint DP in tDPArray)
            {
                if (DP.selected)
                {
                    DP.selected = false;
                    DeployToDPs.Remove(DP);
                    DoNotDeployToDPs.Add(DP);
                }
            }
        }

        private void btnDeployToDPs_Click(object sender, RoutedEventArgs e)
        {
            busyIndicatorMain.IsBusy = true;
            busyIndicatorMain.BusyContent = "Deploy Package to DPs";

            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_DeployToDPsInit);
            proxy.getRequestAsync(currentRequest.requestID, 0);

            
        }

        void proxy_getRequestCompleted_DeployToDPsInit(object sender, getRequestCompletedEventArgs e)
        {
            currentRequest = e.Result;

            if (currentRequest.Status.Equals("Pending Approval") && currentRequest.Stage.Equals("Deployment"))
            {
                currentRequest.Status = "Deploy Package to DPs";

                Application.Current.Resources.Remove("Current Request");
                Application.Current.Resources.Add("Current Request", currentRequest);

                GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
                proxy.saveRequestDPListCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(proxy_saveRequestDPListCompleted);
                proxy.saveRequestDPListAsync(DeployToDPs, currentRequest);
            }
            else
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = true;

                panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;

                busyIndicatorMain.IsBusy = false;
            }
        }

        void proxy_saveRequestDPListCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.saveRequestCompleted += new EventHandler<saveRequestCompletedEventArgs>(proxy_saveRequestCompleted_DeployToDPs);
            proxy.saveRequestAsync(currentRequest);
        }

        void proxy_saveRequestCompleted_DeployToDPs(object sender, saveRequestCompletedEventArgs e)
        {
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();

            currentRequest = e.Result;

            Application.Current.Resources.Remove("Current Request");
            Application.Current.Resources.Add("Current Request", currentRequest);

            busyIndicatorMain.BusyContent = currentRequest.Status;

            if (currentRequest.Status.Equals("Pending Advertisement"))
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = true;

                panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;

                busyIndicatorMain.IsBusy = false;
            }
            else
            {
                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_DeployToDPs);
                proxy.getRequestAsync(currentRequest.requestID, 5);
            }
        }

        void proxy_getRequestCompleted_DeployToDPs(object sender, getRequestCompletedEventArgs e)
        {
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();

            currentRequest = e.Result;

            Application.Current.Resources.Remove("Current Request");
            Application.Current.Resources.Add("Current Request", currentRequest);

            busyIndicatorMain.BusyContent = currentRequest.Status;

            if (currentRequest.Status.Equals("Pending Advertisement"))
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = true;

                panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;

                busyIndicatorMain.IsBusy = false;
            }
            else
            {
                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_DeployToDPs);
                proxy.getRequestAsync(currentRequest.requestID, 5);
            }
        }

        private void btnCreateAdvertisement_Click(object sender, RoutedEventArgs e)
        {
            busyIndicatorMain.IsBusy = true;
            busyIndicatorMain.BusyContent = "Create Advertisement";

            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_CreateAdvertisement_init);
            proxy.getRequestAsync(currentRequest.requestID, 0);
            
        }

        void proxy_getRequestCompleted_CreateAdvertisement_init(object sender, getRequestCompletedEventArgs e)
        {
            currentRequest = e.Result;

            if (currentRequest.Status.Equals("Pending Advertisement") && currentRequest.Stage.Equals("Deployment"))
            {

                currentRequest.Status = "Create Advertisement";

                Application.Current.Resources.Remove("Current Request");
                Application.Current.Resources.Add("Current Request", currentRequest);

                GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
                proxy.saveRequestCompleted += new EventHandler<saveRequestCompletedEventArgs>(proxy_saveRequestCompleted_CreateAdvertisement);
                proxy.saveRequestAsync(currentRequest);
            }
            else
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = false;

                panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;

                busyIndicatorMain.IsBusy = false;

                this.NavigationService.Navigate(new Uri("/Home", UriKind.Relative));
            }
        }
        void proxy_saveRequestCompleted_CreateAdvertisement(object sender, saveRequestCompletedEventArgs e)
        {
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();

            currentRequest = e.Result;

            Application.Current.Resources.Remove("Current Request");
            Application.Current.Resources.Add("Current Request", currentRequest);

            busyIndicatorMain.BusyContent = currentRequest.Status;

            if (!currentRequest.Stage.Equals("Deployment"))
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = false;

                panelDestinationSites.Visibility = System.Windows.Visibility.Visible;
                panelDistributionSites.Visibility = System.Windows.Visibility.Visible;
                busyIndicatorMain.IsBusy = false;

                this.NavigationService.Navigate(new Uri("/Home", UriKind.Relative));
            }
            else
            {
                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_CreateAdvertisement);
                proxy.getRequestAsync(currentRequest.requestID, 5);
            }
        }

        void proxy_getRequestCompleted_CreateAdvertisement(object sender, getRequestCompletedEventArgs e)
        {
            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();

            currentRequest = e.Result;

            Application.Current.Resources.Remove("Current Request");
            Application.Current.Resources.Add("Current Request", currentRequest);

            busyIndicatorMain.BusyContent = currentRequest.Status;

            if (!currentRequest.Stage.Equals("Deployment"))
            {
                btnDeployToDPs.IsEnabled = false;
                btnCreateAdvertisement.IsEnabled = false;

                panelDestinationSites.Visibility = System.Windows.Visibility.Collapsed;
                panelDistributionSites.Visibility = System.Windows.Visibility.Collapsed;

                busyIndicatorMain.IsBusy = false;

                this.NavigationService.Navigate(new Uri("/Home", UriKind.Relative));
            }
            else
            {
                proxy.getRequestCompleted += new EventHandler<getRequestCompletedEventArgs>(proxy_getRequestCompleted_CreateAdvertisement);
                proxy.getRequestAsync(currentRequest.requestID, 5);
            }
        }

        private void gridDestinationSites_GotFocus(object sender, RoutedEventArgs e)
        {
            ADSiteDistribution selectedADSite = ((DataGrid)sender).SelectedItem as ADSiteDistribution;
            SiteComputerView siteCompView = new SiteComputerView(selectedADSite.Computer);
            siteCompView.Show();
        }
        private void gridWorkLog_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            WorkLogEntry entry = (WorkLogEntry)gridWorkLog.SelectedItem;
            if (entry != null)
            {
                WorkLogEntryDetails childWindow = new WorkLogEntryDetails(entry);
                childWindow.boxWorkLogNotes.IsReadOnly = true;
                childWindow.Show();
            }
        }
        private void btnAddWorklogEntry_Click(object sender, RoutedEventArgs e)
        {
            Web.User user = WebContext.Current.User;

            GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
            proxy.getUserFriendlyNameCompleted += new EventHandler<getUserFriendlyNameCompletedEventArgs>(proxy_getUserFriendlyNameCompleted_AddWorkLogEntry);
            proxy.getUserFriendlyNameAsync(user.Name.Split('\\')[1].ToString(), user.Name.Split('\\')[0].ToString());
            busyIndicatorMain.BusyContent = "Creating New Work Log Entry";
            busyIndicatorMain.IsBusy = true;
        }

        void proxy_getUserFriendlyNameCompleted_AddWorkLogEntry(object sender, getUserFriendlyNameCompletedEventArgs e)
        {
            busyIndicatorMain.IsBusy = false;
            WorkLogEntry entry = new WorkLogEntry()
            {
                Note = String.Empty,
                NoteDate = DateTime.UtcNow,
                RequestID = currentRequest.requestID,
                UserName = e.Result.ToString(),
                WorkLogID = System.Guid.NewGuid().ToString()
            };

            WorkLogEntryDetails childWindow = new WorkLogEntryDetails(entry);
            childWindow.Closed += new EventHandler(childWindow_Closed_WorkLogEntry);

            childWindow.Show();
        }

        void childWindow_Closed_WorkLogEntry(object sender, EventArgs e)
        {
            WorkLogEntryDetails childWindow = (WorkLogEntryDetails)sender;
            if (childWindow.DialogResult.Value == true)
            {
                busyIndicatorMain.IsBusy = true;
                busyIndicatorMain.BusyContent = "Saving Work Log Entry";
                GranitePackagingServiceSoapClient proxy = new GranitePackagingServiceSoapClient();
                proxy.createWorkLogEntryCompleted += new EventHandler<createWorkLogEntryCompletedEventArgs>(proxy_createWorkLogEntryCompleted);
                proxy.createWorkLogEntryAsync(childWindow.entry.UserName, childWindow.entry.RequestID, childWindow.entry.Note, childWindow.entry.NoteDate);
            }
        }

        void proxy_createWorkLogEntryCompleted(object sender, createWorkLogEntryCompletedEventArgs e)
        {
            busyIndicatorMain.IsBusy = false;
            WorkLogEntry modifiedWorkLogEntry = e.Result;
            modifiedWorkLogEntry.NoteDate = modifiedWorkLogEntry.NoteDate.ToLocalTime();
            workLog.Add(modifiedWorkLogEntry);
        }
    }
}
